using BCrypt.Net;
using MediPlatform.Domain.Order;
using MediPlatform.Infeartructure;
using MediPlatform.Read.Api.Models;
using Microsoft.EntityFrameworkCore;
using System.Security.Cryptography;
using System.Text;

namespace MediPlatform.Read.Api.Services
{
    /// <summary>
    /// 认证服务
    /// </summary>
    public class AuthService
    {
        private readonly MyDbContext _context;
        private readonly JwtService _jwtService;
        private readonly ILogger<AuthService> _logger;

        public AuthService(MyDbContext context, JwtService jwtService, ILogger<AuthService> logger)
        {
            _context = context;
            _jwtService = jwtService;
            _logger = logger;
        }

        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="request">登录请求</param>
        /// <returns>登录响应</returns>
        public async Task<LoginResponse> LoginAsync(LoginRequest request)
        {
            try
            {
                // 查找用户（支持用户名或邮箱登录）
                var user = await _context.User
                    .FirstOrDefaultAsync(u => 
                        u.Username == request.UsernameOrEmail || 
                        u.Email == request.UsernameOrEmail);

                if (user == null)
                {
                    _logger.LogWarning("登录失败：用户不存在 - {UsernameOrEmail}", request.UsernameOrEmail);
                    return new LoginResponse
                    {
                        Success = false,
                        Message = "用户名或密码错误"
                    };
                }

                // 验证密码
                if (!VerifyPassword(request.Password, user.PasswordHash))
                {
                    _logger.LogWarning("登录失败：密码错误 - {Username}", user.Username);
                    return new LoginResponse
                    {
                        Success = false,
                        Message = "用户名或密码错误"
                    };
                }

                // 生成用户信息
                var userInfo = new UserInfo
                {
                    Id = user.Id ?? 0,
                    UserId = user.UserId ?? string.Empty,
                    Username = user.Username ?? string.Empty,
                    Email = user.Email ?? string.Empty,
                    Role = user.Role ?? "user",
                    CreatedAt = user.CreatedAt ?? DateTime.Now
                };

                // 生成令牌
                var accessToken = _jwtService.GenerateAccessToken(userInfo);
                var refreshToken = _jwtService.GenerateRefreshToken();

                // 计算过期时间
                var expiresIn = Convert.ToInt32(TimeSpan.FromMinutes(30).TotalSeconds);

                _logger.LogInformation("用户登录成功 - {Username}", user.Username);

                return new LoginResponse
                {
                    Success = true,
                    Message = "登录成功",
                    AccessToken = accessToken,
                    RefreshToken = refreshToken,
                    ExpiresIn = expiresIn,
                    User = userInfo
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "登录过程中发生错误");
                return new LoginResponse
                {
                    Success = false,
                    Message = "登录失败，请稍后重试"
                };
            }
        }

        /// <summary>
        /// 用户注册
        /// </summary>
        /// <param name="request">注册请求</param>
        /// <returns>注册响应</returns>
        public async Task<LoginResponse> RegisterAsync(RegisterRequest request)
        {
            try
            {
                // 检查用户名是否已存在
                if (await _context.User.AnyAsync(u => u.Username == request.Username))
                {
                    return new LoginResponse
                    {
                        Success = false,
                        Message = "用户名已存在"
                    };
                }

                // 检查邮箱是否已存在
                if (await _context.User.AnyAsync(u => u.Email == request.Email))
                {
                    return new LoginResponse
                    {
                        Success = false,
                        Message = "邮箱已被注册"
                    };
                }

                // 创建新用户
                var user = new User
                {
                    UserId = GenerateUserId(),
                    Username = request.Username,
                    Email = request.Email,
                    PasswordHash = HashPassword(request.Password),
                    Role = request.Role,
                    CreatedAt = DateTime.Now,
                    UpdatedAt = DateTime.Now
                };

                _context.User.Add(user);
                await _context.SaveChangesAsync();

                // 生成用户信息
                var userInfo = new UserInfo
                {
                    Id = user.Id ?? 0,
                    UserId = user.UserId ?? string.Empty,
                    Username = user.Username ?? string.Empty,
                    Email = user.Email ?? string.Empty,
                    Role = user.Role ?? "user",
                    CreatedAt = user.CreatedAt ?? DateTime.Now
                };

                // 生成令牌
                var accessToken = _jwtService.GenerateAccessToken(userInfo);
                var refreshToken = _jwtService.GenerateRefreshToken();

                // 计算过期时间
                var expiresIn = Convert.ToInt32(TimeSpan.FromMinutes(30).TotalSeconds);

                _logger.LogInformation("用户注册成功 - {Username}", user.Username);

                return new LoginResponse
                {
                    Success = true,
                    Message = "注册成功",
                    AccessToken = accessToken,
                    RefreshToken = refreshToken,
                    ExpiresIn = expiresIn,
                    User = userInfo
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "注册过程中发生错误");
                return new LoginResponse
                {
                    Success = false,
                    Message = "注册失败，请稍后重试"
                };
            }
        }

        /// <summary>
        /// 刷新令牌
        /// </summary>
        /// <param name="request">刷新令牌请求</param>
        /// <returns>刷新令牌响应</returns>
        public async Task<RefreshTokenResponse> RefreshTokenAsync(RefreshTokenRequest request)
        {
            try
            {
                // 这里应该验证刷新令牌的有效性
                // 为了简化，我们直接生成新的令牌
                // 在实际应用中，应该将刷新令牌存储在数据库中并验证

                var refreshToken = _jwtService.GenerateRefreshToken();
                var expiresIn = Convert.ToInt32(TimeSpan.FromMinutes(30).TotalSeconds);

                return new RefreshTokenResponse
                {
                    Success = true,
                    Message = "令牌刷新成功",
                    RefreshToken = refreshToken,
                    ExpiresIn = expiresIn
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "刷新令牌过程中发生错误");
                return new RefreshTokenResponse
                {
                    Success = false,
                    Message = "令牌刷新失败，请重新登录"
                };
            }
        }

        /// <summary>
        /// 验证密码
        /// </summary>
        /// <param name="password">明文密码</param>
        /// <param name="hash">密码哈希</param>
        /// <returns>是否验证成功</returns>
        private bool VerifyPassword(string password, string hash)
        {
            try
            {
                return BCrypt.Net.BCrypt.Verify(password, hash);
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 哈希密码
        /// </summary>
        /// <param name="password">明文密码</param>
        /// <returns>密码哈希</returns>
        private string HashPassword(string password)
        {
            return BCrypt.Net.BCrypt.HashPassword(password, BCrypt.Net.BCrypt.GenerateSalt(12));
        }

        /// <summary>
        /// 生成用户ID
        /// </summary>
        /// <returns>用户ID</returns>
        private string GenerateUserId()
        {
            var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
            var random = new Random();
            var randomPart = random.Next(1000, 9999);
            return $"U{timestamp}{randomPart}";
        }

        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <returns>用户信息</returns>
        public async Task<UserInfo?> GetUserInfoAsync(long userId)
        {
            var user = await _context.User.FindAsync(userId);
            if (user == null) return null;

            return new UserInfo
            {
                Id = user.Id ?? 0,
                UserId = user.UserId ?? string.Empty,
                Username = user.Username ?? string.Empty,
                Email = user.Email ?? string.Empty,
                Role = user.Role ?? "user",
                CreatedAt = user.CreatedAt ?? DateTime.Now
            };
        }
    }
} 